#include "OptionsState.h"
#include "MainMenuState.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_AudioManager.h"
#include "../SGD Wrappers/SGD_Event.h"
#include "Game.h"
#include "BitmapFont.h"
#include "Menu.h"
#include "MenuCursor.h"
#include <vector>
#include <sstream>
#include <fstream>
#include "../TinyXML/tinyxml.h"

OptionsState* OptionsState::GetInstance()
{
	static OptionsState instance;
	return &instance;
}

void OptionsState::Enter()
{
	//Initialize audio levels
	sound = SGD::AudioManager::GetInstance()->GetMasterVolume(
		SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS);
	music = SGD::AudioManager::GetInstance()->GetMasterVolume(
		SGD::AudioManager::VolumeType::MASTER_MUSIC);

	//load in XML menu options
	SGD::GraphicsManager::GetInstance()->SetClearColor({ 0, 0, 0 });
	menu = new Menu;
	menu->Initialize("resources/xml/options.xml");
	std::vector<SGD::Point> p;
	for (unsigned int i = 0; i < menu->menuItems.size(); i++)
	{
		p.push_back(menu->menuItems[i].GetPosition());
	}

	//create and initialize the cursor
	cursor = new MenuCursor;
	cursor->Initialize(p);
	cursor->SetOffset({ -115, 15 });
	cursor->SetSize({ 5, 5 });
	cursor->SetPosition(cursor->GetPositions()[0]);

	//Set Data
	std::ostringstream ossSound;
	ossSound << sound;
	menu->menuItems[0].buttons[0].SetData(ossSound.str());
	std::ostringstream ossMusic;
	ossMusic << music;
	menu->menuItems[1].buttons[0].SetData(ossMusic.str());
	background = SGD::GraphicsManager::GetInstance()->LoadTexture("resources/images/shadowmancer_menu.png");

}

void OptionsState::Exit()
{
	SGD::GraphicsManager::GetInstance()->UnloadTexture(background);

	delete menu;
	menu = nullptr;
	delete cursor;
	cursor = nullptr;

	TiXmlDocument doc;
	TiXmlDeclaration*pDec = new TiXmlDeclaration("1.0", "UTF-8", "");
	doc.LinkEndChild(pDec);
	TiXmlElement*root = new TiXmlElement("Config");
	root->SetAttribute("MusVol", music);
	root->SetAttribute("SFXVol", sound);
	root->SetAttribute("FullScreen", Game::GetInstance()->GetWindowed());
	doc.LinkEndChild(root);
	doc.SaveFile("resources/xml/config.xml");

	std::ofstream out("resources/options.txt");
	/*if (out.is_open())
	{
		out << SGD::AudioManager::GetInstance()->GetMasterVolume(
			SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS)
			<< ',' <<
			SGD::AudioManager::GetInstance()->GetMasterVolume(
			SGD::AudioManager::VolumeType::MASTER_MUSIC);
	}*/
	SGD::AudioManager::GetInstance()->SetMasterVolume(
		SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS, sound);
	SGD::AudioManager::GetInstance()->SetMasterVolume(
		SGD::AudioManager::VolumeType::MASTER_MUSIC, music);
}

bool OptionsState::Input()
{
	SGD::AudioManager* audio = SGD::AudioManager::GetInstance();
	SGD::InputManager* input = SGD::InputManager::GetInstance();
	if (input->IsKeyPressed(SGD::Key::Down) == true
		|| input->IsDPadPressed(0, SGD::DPad::Down))
	{
		SGD::Event e = { "MENUMOVE" };
		e.SendEventNow(nullptr);
		cursPos++;
		if ((unsigned int)cursPos > cursor->GetPositions().size() - 1)
			cursPos = 0;
	}
	if (input->IsKeyPressed(SGD::Key::Up) == true
		|| input->IsDPadPressed(0, SGD::DPad::Up))
	{
		SGD::Event e = { "MENUMOVE" };
		e.SendEventNow(nullptr);
		cursPos--;
		if (cursPos < 0)
			cursPos = cursor->GetPositions().size() - 1;
	}
	if (input->IsKeyPressed(SGD::Key::Enter) == true
		|| input->IsKeyPressed(SGD::Key::LButton) == true
		|| input->IsButtonPressed(0, 0))
	{
		SGD::Event e = { "MENUSELECT" };
		e.SendEventNow(nullptr);
		if (cursPos == 2)
		{
			Game::GetInstance()->ChangeWindowed();
		}
		if (cursPos == 3)
		{
			Game::GetInstance()->ChangeState(MainMenuState::GetInstance());
			return true;
		}
	}
	if (input->IsKeyPressed(SGD::Key::Left)
		|| input->IsDPadPressed(0, SGD::DPad::Left))
	{
		SGD::Event e = { "MENUSELECT" };
		e.SendEventNow(nullptr);
		if (cursPos == 0)
		{
			sound -= 5;
			if (sound < 0)
				sound = 0;
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS, sound);
		}
		else if (cursPos == 1)
		{
			music -= 5;
			if (music < 0)
				music = 0;
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_MUSIC, music);
		}
	}
	else if (input->IsKeyPressed(SGD::Key::Right)
		|| input->IsDPadPressed(0, SGD::DPad::Right))
	{
		SGD::Event e = { "MENUSELECT" };
		e.SendEventNow(nullptr);
		if (cursPos == 0)
		{
			sound += 5;
			if (sound > 100)
				sound = 100;
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS, sound);
		}
		else if (cursPos == 1)
		{
			music += 5;
			if (music > 100)
				music = 100;
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_MUSIC, music);
		}
	}
	else if (input->IsKeyPressed(SGD::Key::LButton))
	{
		SGD::Event e = { "MENUSELECT" };
		e.SendEventNow(nullptr);
		SGD::Rectangle rect{
		input->GetMousePosition(), SGD::Size{ 1, 1 } };
		if (cursPos == 0)
		{
			if (menu->menuItems[0].buttons[1].GetRect().IsIntersecting(rect))
			{
				sound += 5;
				if (sound > 100)
					sound = 100;
			}
			else if (menu->menuItems[0].buttons[0].GetRect().IsIntersecting(rect))
			{
				sound -= 5;
				if (sound < 0)
					sound = 0;
			}
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_SOUND_EFFECTS, sound);
		}
		else if (cursPos == 1)
		{
			if (menu->menuItems[1].buttons[1].GetRect().IsIntersecting(rect))
			{
				music += 5;
				if (music > 100)
					music = 100;
			}
			else if (menu->menuItems[1].buttons[0].GetRect().IsIntersecting(rect))
			{
				music -= 5;
				if (music < 0)
					music = 0;
			}
			audio->SetMasterVolume(SGD::AudioManager::VolumeType::MASTER_MUSIC, music);
		}
	}

	if (input->IsAnyKeyPressed())
		mouseInput = false;
	else if (input->GetMouseMovement() != SGD::Vector{ 0, 0 })
		mouseInput = true;

	return true;
}

void OptionsState::Update(float elapsedTime)
{
	std::ostringstream ossSound;
	ossSound << sound;
	menu->menuItems[0].buttons[0].SetData(ossSound.str());
	std::ostringstream ossMusic;
	ossMusic << music;
	menu->menuItems[1].buttons[0].SetData(ossMusic.str());
	if (!mouseInput)
		cursor->SetPosition(cursor->GetPositions()[cursPos]);
	else
	{
		SGD::InputManager* input = SGD::InputManager::GetInstance();
		SGD::Rectangle rect{
			input->GetMousePosition(), SGD::Size{ 1, 1 } };
		for (unsigned int i = 0; i < menu->menuItems.size(); i++)
		{
			if (menu->menuItems[i].buttons.size() > 1)
			{
				if (menu->menuItems[i].buttons[0].GetRect().IsIntersecting(rect))
				{
					if (cursPos != i)
					{
						SGD::Event e = { "MENUMOVE" };
						e.SendEventNow(nullptr);
					}
					cursor->SetPosition(cursor->GetPositions()[i]);
					cursPos = i;
				}
				else if (menu->menuItems[i].buttons[1].GetRect().IsIntersecting(rect))
				{
					if (cursPos != i)
					{
						SGD::Event e = { "MENUMOVE" };
						e.SendEventNow(nullptr);
					}
					cursor->SetPosition(cursor->GetPositions()[i]);
					cursPos = i;
				}
			}
			else if (menu->menuItems[i].buttons[0].GetRect().IsIntersecting(rect))
			{
				if (cursPos != i)
				{
					SGD::Event e = { "MENUMOVE" };
					e.SendEventNow(nullptr);
				}
				cursor->SetPosition(cursor->GetPositions()[i]);
				cursPos = i;
			}
		}
	}
	menu->Update(elapsedTime);
}

void OptionsState::Render()
{
	SGD::GraphicsManager::GetInstance()->DrawTexture(background, {}, {}, {}, {}, { 1, 1 });
	BitmapFont* font = Game::GetInstance()->GetFont();
	SGD::InputManager* input = SGD::InputManager::GetInstance();
	font->Draw("Options", 5, 5, 1.0f, { 255, 255, 255 });
	menu->Render();
	cursor->Render();
}